"""

@Time: 2021/5/30 19:36
@Author:
@File: exception_handler.py
"""
from fastapi import FastAPI, Request, status
from fastapi.responses import JSONResponse
from exception import BusinessException, TokenVerifyException, RolePermissionError
from elasticsearch.exceptions import NotFoundError as EsNotFoundError
from schema.resp import RestfulModel, RespCode
import error_code


def register_exception_handlers(app: FastAPI):
    """
    为 app 注册异常处理器
    """

    @app.exception_handler(BusinessException)
    async def business_exec_handler(request: Request, exc: BusinessException):
        return JSONResponse(
            status_code=status.HTTP_400_BAD_REQUEST,
            content=RestfulModel(code=error_code.BUSINESS_EXEC,
                                 message='业务异常',
                                 data=str(exc)).dict()
        )

    @app.exception_handler(TokenVerifyException)
    async def token_verify_exc_handler(request: Request, exc: TokenVerifyException):
        return JSONResponse(
            status_code=status.HTTP_401_UNAUTHORIZED,
            content=RestfulModel(code=RespCode.FIELD,
                                 message=exc.msg,
                                 data=None).dict()
        )

    @app.exception_handler(RolePermissionError)
    async def token_verify_exc_handler(request: Request, exc: RolePermissionError):
        return JSONResponse(
            status_code=status.HTTP_403_FORBIDDEN,
            content=RestfulModel(code=RespCode.FIELD,
                                 message='权限不允许',
                                 data=None).dict()
        )

    @app.exception_handler(EsNotFoundError)
    async def elasticsearch_not_found_error_handler(request: Request, exc: EsNotFoundError):
        try:
            root_cause = exc.info.get('error').get('root_cause')[0]
            error_type = root_cause.get('type')
            error_reason = root_cause.get('reason')
            error_data = f'{error_type}:{error_reason}'
        except Exception:
            error_data = 'Elasticsearch Not Found Error'
        return JSONResponse(
            status_code=status.HTTP_400_BAD_REQUEST,
            content=RestfulModel(code=RespCode.FIELD,
                                 message='请修改 ES 相关配置',
                                 data=error_data).dict()
        )